#include "Calendar/GregorianConstants.hpp"
#include <cmath>
#include <tuple>

std::tuple<int, int, int> GregorianConstants::GetHuiLi(double d0) noexcept
{
    // 以下算法使用Excel测试得到,测试时主要关心年临界与月临界;
    // 10631为一周期(30年);
    double d = d0 + 503105.0;
    double z = floor(d / 10631.0);
    d -= z * 10631.0;
    // 加0.5的作用是保证闰年正确(一周中的闰年是第2,5,7,10,13,16,18,21,24,26,29年);
    double y = floor((d + 0.5) / 354.366);
    d -= floor(y * 354.366 + 0.5);
    // 分子加0.11,分母加0.01的作用是第354或355天的的月分保持为12月(m=11);
    double m = floor((d + 0.11) / 29.51);
    d -= floor(m * 29.5 + 0.5);
    return std::make_tuple((int)(z * 30 + y + 1), (int)m + 1, (int)d + 1);
}

